#pragma once

#if 0
#include "treewalker.h"

class Driver;
class Uic;
class DomBrush;
class DomFont;
class DomResourceIcon;
class DomSizePolicy;
class DomStringList;
struct Option;

// Handle for a flat DOM font to get comparison functionality required for maps
class FontHandle
{
public:
	FontHandle(const DomFont *domFont);
	int compare(const FontHandle &) const;
private:
	const DomFont *m_domFont;
};

inline bool operator ==(const FontHandle &f1, const FontHandle &f2) { return f1.compare(f2) == 0; }
inline bool operator  <(const FontHandle &f1, const FontHandle &f2) { return f1.compare(f2) < 0; }

// Handle for a flat DOM icon to get comparison functionality required for maps
class IconHandle
{
public:
	IconHandle(const DomResourceIcon *domIcon);
	int compare(const IconHandle &) const;
private:
	const DomResourceIcon *m_domIcon;
};

inline bool operator == (const IconHandle &i1, const IconHandle &i2) { return i1.compare(i2) == 0; }
inline bool operator < (const IconHandle &i1, const IconHandle &i2) { return i1.compare(i2) < 0; }

// Handle for a flat DOM size policy to get comparison functionality required for maps
class SizePolicyHandle
{
public:
	SizePolicyHandle(const DomSizePolicy *domSizePolicy);
	int compare(const SizePolicyHandle &) const;

private:
	const DomSizePolicy *m_domSizePolicy;
};

inline bool operator ==(const SizePolicyHandle &f1, const SizePolicyHandle &f2) { return f1.compare(f2) == 0; }
inline bool operator  <(const SizePolicyHandle &f1, const SizePolicyHandle &f2) { return f1.compare(f2) < 0; }


struct WriteInitialization : public TreeWalker
{
	typedef std::vector<DomProperty*> DomPropertyList;
	typedef std::map<CString, DomProperty*> DomPropertyMap;

	WriteInitialization(Uic *uic, bool activateScripts);

	//
	// widgets
	//
	void acceptUI(DomUI *node) override;
	void acceptWidget(DomWidget *node) override;
	void acceptWidgetScripts(const DomScripts &, DomWidget *node, const  DomWidgets &childWidgets) override;

	void acceptLayout(DomLayout *node) override;
	void acceptSpacer(DomSpacer *node) override;
	void acceptLayoutItem(DomLayoutItem *node) override;

	//
	// actions
	//
	void acceptActionGroup(DomActionGroup *node) override;
	void acceptAction(DomAction *node) override;
	void acceptActionRef(DomActionRef *node) override;

	//
	// tab stops
	//
	void acceptTabStops(DomTabStops *tabStops) override;

	//
	// custom widgets
	//
	void acceptCustomWidgets(DomCustomWidgets *node) override;
	void acceptCustomWidget(DomCustomWidget *node) override;

	//
	// layout defaults/functions
	//
	void acceptLayoutDefault(DomLayoutDefault *node) override{ m_LayoutDefaultHandler.acceptLayoutDefault(node); }
	void acceptLayoutFunction(DomLayoutFunction *node) override{ m_LayoutDefaultHandler.acceptLayoutFunction(node); }

	//
	// signal/slot connections
	//
	void acceptConnection(DomConnection *connection) override;

	//
	// images
	//
	void acceptImage(DomImage *image) override;

	enum {
		Use43UiFile = 0,
		TopLevelMargin,
		ChildMargin,
		SubLayoutMargin
	};

private:
	static CString domColor2QString(const DomColor *c);

	CString iconCall(const DomProperty *prop);
	CString pixCall(const DomProperty *prop) const;
	CString pixCall(const CString &type, const CString &text) const;
	CString trCall(const CString &str, const CString &comment = CString()) const;
	CString trCall(DomString *str, const CString &defaultString = CString()) const;
	CString noTrCall(DomString *str, const CString &defaultString = CString()) const;
	CString autoTrCall(DomString *str, const CString &defaultString = CString()) const;
	inline CTextStream &autoTrOutput(const DomProperty *str);
	CTextStream &autoTrOutput(const DomString *str, const CString &defaultString = CString());
	// Apply a comma-separated list of values using a function "setSomething(int idx, value)"
	void writePropertyList(const CString &varName, const CString &setFunction, const CString &value, const CString &defaultValue);

	enum { WritePropertyIgnoreMargin = 1, WritePropertyIgnoreSpacing = 2, WritePropertyIgnoreObjectName = 4 };
	CString writeStringListProperty(const DomStringList *list) const;
	void writeProperties(const CString &varName, const CString &className, const DomPropertyList &lst, unsigned flags = 0);
	void writeColorGroup(DomColorGroup *colorGroup, const CString &group, const CString &paletteName);
	void writeBrush(const DomBrush *brush, const CString &brushName);

	//
	// special initialization
	//
	class Item {
	public:
		Item(const CString &itemClassName, const CString &indent, CTextStream &setupUiStream, CTextStream &retranslateUiStream, Driver *driver);
		~Item();
		enum EmptyItemPolicy {
			DontConstruct,
			ConstructItemOnly,
			ConstructItemAndVariable
		};
		CString writeSetupUi(const CString &parent, EmptyItemPolicy emptyItemPolicy = ConstructItemOnly);
		void writeRetranslateUi(const CString &parentPath);
		void addSetter(const CString &setter, const CString &directive = CString(), bool translatable = false); // don't call it if you already added *this as a child of another Item
		void addChild(Item *child); // all setters should already been added
		int setupUiCount() const { return m_setupUiData.setters.size(); }
		int retranslateUiCount() const { return m_retranslateUiData.setters.size(); }
	private:
		struct ItemData
		{
			ItemData() : policy(DontGenerate) {}
			std::multimap<CString, CString> setters; // directive to setter
			std::set<CString> directives;
			enum TemporaryVariableGeneratorPolicy { // policies with priority, number describes the priority
				DontGenerate = 1,
				GenerateWithMultiDirective = 2,
				Generate = 3
			} policy;
		};
		ItemData m_setupUiData;
		ItemData m_retranslateUiData;
		std::vector<Item *> m_children;
		Item *m_parent;

		const CString m_itemClassName;
		const CString m_indent;
		CTextStream &m_setupUiStream;
		CTextStream &m_retranslateUiStream;
		Driver *m_driver;
	};

	void addInitializer(Item *item,
		const CString &name, int column, const CString &value, const CString &directive = CString(), bool translatable = false) const;
	void addQtFlagsInitializer(Item *item, const DomPropertyMap &properties,
		const CString &name, int column = -1) const;
	void addQtEnumInitializer(Item *item,
		const DomPropertyMap &properties, const CString &name, int column = -1) const;
	void addBrushInitializer(Item *item,
		const DomPropertyMap &properties, const CString &name, int column = -1);
	void addStringInitializer(Item *item,
		const DomPropertyMap &properties, const CString &name, int column = -1, const CString &directive = CString()) const;
	void addCommonInitializers(Item *item,
		const DomPropertyMap &properties, int column = -1);

	void initializeMenu(DomWidget *w, const CString &parentWidget);
	void initializeComboBox(DomWidget *w);
	void initializeListWidget(DomWidget *w);
	void initializeTreeWidget(DomWidget *w);
	std::vector<Item *> initializeTreeWidgetItems(const std::vector<DomItem *> &domItems);
	void initializeTableWidget(DomWidget *w);

	CString disableSorting(DomWidget *w, const CString &varName);
	void enableSorting(DomWidget *w, const CString &varName, const CString &tempName);

	CString findDeclaration(const CString &name);
	DomWidget *findWidget(CString widgetClass);
	DomImage *findImage(const CString &name) const;

	bool isValidObject(const CString &name) const;

private:
	CString writeFontProperties(const DomFont *f);
	CString writeIconProperties(const DomResourceIcon *i);
	CString writeSizePolicy(const DomSizePolicy *sp);
	CString writeBrushInitialization(const DomBrush *brush);
	void addButtonGroup(const DomWidget *node, const CString &varName);
#ifdef FULLY
	void addWizardPage(const CString &pageVarName, const DomWidget *page, const CString &parentWidget);
#endif

	const Uic *m_uic;
	Driver *m_driver;
	CTextStream &m_output;
	const Option &m_option;
	CString m_indent;
	CString m_dindent;
	bool m_stdsetdef;

	struct Buddy
	{
		Buddy(const CString &oN, const CString &b)
			: objName(oN), buddy(b) {}
		CString objName;
		CString buddy;
	};

	std::stack<DomWidget*> m_widgetChain;
	std::stack<DomLayout*> m_layoutChain;
	std::stack<DomActionGroup*> m_actionGroupChain;
	std::vector<Buddy> m_buddies;

	std::set<CString> m_buttonGroups;
	std::map<CString, DomWidget*> m_registeredWidgets;
	std::map<CString, DomImage*> m_registeredImages;
	std::map<CString, DomAction*> m_registeredActions;
	typedef std::map<unsigned int, CString> ColorBrushHash;
	ColorBrushHash m_colorBrushHash;
	// Map from font properties to  font variable name for reuse
	// Map from size policy to  variable for reuse
	typedef std::map<FontHandle, CString> FontPropertiesNameMap;
	typedef std::map<IconHandle, CString> IconPropertiesNameMap;
	typedef std::map<SizePolicyHandle, CString> SizePolicyNameMap;
	FontPropertiesNameMap m_fontPropertiesNameMap;
	IconPropertiesNameMap m_iconPropertiesNameMap;
	SizePolicyNameMap     m_sizePolicyNameMap;

	class LayoutDefaultHandler
	{
	public:
		LayoutDefaultHandler();
		void acceptLayoutDefault(DomLayoutDefault *node);
		void acceptLayoutFunction(DomLayoutFunction *node);

		// Write out the layout margin and spacing properties applying the defaults.
		void writeProperties(const CString &indent, const CString &varName,
			const DomPropertyMap &pm, int marginType,
			bool suppressMarginDefault, CTextStream &str) const;

	private:
		void writeProperty(int p, const CString &indent, const CString &objectName, const DomPropertyMap &pm,
			const CString &propertyName, const CString &setter, int defaultStyleValue,
			bool suppressDefault, CTextStream &str) const;

		enum Properties { Margin, Spacing, NumProperties };
		enum StateFlags { HasDefaultValue = 1, HasDefaultFunction = 2 };
		unsigned m_state[NumProperties];
		int m_defaultValues[NumProperties];
		CString m_functions[NumProperties];
	};

	// layout defaults
	LayoutDefaultHandler m_LayoutDefaultHandler;
	int m_layoutMarginType;

	CString m_generatedClass;
	CString m_mainFormVarName;
	bool m_mainFormUsedInRetranslateUi;

	CString m_delayedInitialization;
	//CTextStream m_delayedOut;

	CString m_refreshInitialization;
	//CTextStream m_refreshOut;

	CString m_delayedActionInitialization;
	//CTextStream m_actionOut;
	const bool m_activateScripts;

	bool m_layoutWidget;
	bool m_firstThemeIcon;
};

#endif